home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / 3dlib15.zip / RTOBJW.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-27  |  33KB  |  792 lines

  1. (******************************************************************************
  2. *                                    rtObj                                    *
  3. *      please notice -                                                        *
  4. *      this unit includes both the object3d unit, and the superobj unit,      *
  5. *      and it is used with no reference to the window GUI library,            *
  6. *      uses project3, instead of prjWind                                      *
  7. ******************************************************************************)
  8. Unit rtObjW;
  9.  
  10. (*******************************************************************************
  11. *                                 3D Objects                                   *
  12. *                                 ----------                                   *
  13. *                                                                              *
  14. *   A 3D object is a collection of points and lines in the 3D universe,        *
  15. *   that represent the body we want to draw on the screen.                     *
  16. *   A 3D object is allways centered around point (0, 0, 0) in the 3D universe. *
  17. *   (Its center of gravity assuming it is has a uniform weight distribution    *
  18. *    is in point (0, 0, 0)                                                     *
  19. *   At any moment during the object's life, we know it's distance from the     *
  20. *   origin, And it's rotation using reveres rotation CTM.                      *
  21. *                                                                              *
  22. *   3D Object methods:                                                         *
  23. *      constructor Open                                                        *
  24. *      destructor  CloseMe                                                     *
  25. *      procedures: Rotate, Scale, Move, Show, Hide, Load, Save                 *
  26. *                  SetToOrigin, Paint                                          *
  27. *                                                                              *
  28. *******************************************************************************)
  29.  
  30. interface
  31.  
  32. uses
  33.     winTypes
  34.     ,winProcs
  35.     ,Ctm3dw
  36.     ,hdr3dw
  37.     ,projectw
  38.     ;
  39.  
  40. type
  41.     f_real = file of real;
  42.  
  43.     {===================================================================}
  44.     {  Base object is the base class for 3D-objects. some functions     }
  45.     { are dummy virtual do-nothing, which are are implemented only for  }
  46.     { the descendend objects derived from BaseObject                    }
  47.     {===================================================================}
  48.  
  49.     BaseObjectPtr = ^BaseObject;
  50.     BaseObject = object
  51.        MyCtm       : Ctm;      { This CTM applied to the object gives the  }
  52.                                {  objects Position after transformations   }
  53.        Name        : String;   { Identifies the object                     }
  54.        myColor     : word;     { Main color for the object                 }
  55.        Location    : point3d;  { Central of gravity in real space          }
  56.        scrPntUpdt  : boolean;  { True if screen points updated             }
  57.  
  58.        constructor open(myName : string; color : word);
  59.        destructor  CloseMe; virtual;
  60.        procedure   show(dc : hdc); virtual;
  61.        procedure   hide(dc : hdc); virtual;
  62.        procedure   paint(dc : hdc); virtual; {in specified color}
  63.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  64.        procedure   move(axis : axisType; by : real); virtual;
  65.        procedure   translate(dx, dy, dz : integer); virtual;
  66.                {multy dimentional move in 1 call}
  67.        procedure   scale(axis : axisType; factor : real); virtual;
  68.        procedure   allScale(sx, sy, sz : real); virtual;
  69.                {multy dimentional scale in 1 call}
  70.        procedure   rotate(axis : axisType; deg : real); virtual;
  71.  
  72.        procedure   goto3dPos(x, y, z : real); virtual; {translate to absolute place}
  73.        procedure   setToOrigin; virtual;
  74.                {translate to 0,0,0, update points, and set myCtm to unit}
  75.        procedure   calcLocation; virtual; {set Location to central gravity}
  76.        procedure   deleteTransform; virtual; {set MyCtm to unit}
  77.  
  78.        function load : word; virtual; {from disk}
  79.        function save : word; virtual; {to   disk}
  80.        procedure writeMe(var elementFile : f_real); virtual; {to disk .. without opening file..}
  81.        procedure readMe(var elementFile : f_real); virtual;
  82.     end;
  83.     {===================================================================}
  84.     { Obj3d is an object which represents a 3-D object with a poligon  }
  85.     {  mesh.                                                           }
  86.     {===================================================================}
  87.  
  88.     Obj3dPtr = ^Obj3d;
  89.     Obj3d = object(BaseObject)
  90.        Points      : array[1..MaxPoints] of point3d;
  91.        Lines       : array[1..MaxLines]   of Line3d;
  92.        scrPoints   : array[1..MaxPoints] of screenPoints;
  93.        NumOfLines  : integer;
  94.        NumOfPoints : integer;
  95.        ReverseRot  : Ctm;  { Saves only the reverse rotations }
  96.        unReverseRot: Ctm;  { reverse of the above}
  97.  
  98.        constructor open(myName : string; ref : point3d; color : word);
  99.        destructor  CloseMe; virtual;
  100.        procedure   paint(dc : hdc); virtual; {in specified color}
  101.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  102.  
  103.        procedure   calcLocation; virtual; {set Location to central gravity}
  104.        procedure   setToOrigin; virtual;
  105.  
  106.        procedure writeMe(var elementFile : f_real); virtual;
  107.        procedure readMe(var elementFile : f_real); virtual;
  108.     end;
  109.  
  110. const
  111.    maxSubObjects = 15;
  112.  
  113. type
  114.     complexObjPtr = ^complexObj;
  115.     ComplexObj = object(BaseObject)
  116.        childs      : array [1..maxSubObjects] of obj3dPtr;
  117.        ctms        : array [1..maxSubObjects] of ctm;
  118.        numOfChilds : integer; {counter of # of obj3d childs}
  119.  
  120.        constructor open(myName : string; color : word);
  121.        destructor  closeMe; virtual;
  122.        procedure   updateScreenPoints; virtual;
  123.        procedure   writeMe(var elementFile : f_real); virtual;
  124.        procedure   readMe(var elementFile : f_real); virtual;
  125.        procedure   calcLocation; virtual;
  126.        procedure   paint(dc : hdc); virtual;
  127.        procedure   move(axis : axisType; by : real); virtual;
  128.        procedure   rotate(axis : axisType; deg : real); virtual;
  129.        procedure   scale(axis : axisType; factor : real); virtual;
  130.  
  131.        function    addSubObject(myName : string; refPoint : point3d) : word;
  132.        function    getChildPtr(index : integer) : obj3dPtr;
  133.        procedure   rotateChild(child : integer; axis : axisType;
  134.                                        deg : real);
  135.        procedure   scaleChild(child : integer; axis : axisType;
  136.                                        factor : real);
  137.        procedure   moveChild(child : integer; axis : axisType;
  138.                                by : real);
  139.     end;
  140.  
  141.  
  142. implementation
  143.  
  144.  
  145.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  146.     {                     BaseObject implementation                        }
  147.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  148.  
  149. (*******************************************************************************
  150. *                              BaseObject.Open                                 *
  151. *******************************************************************************)
  152. constructor BaseObject.Open;
  153. begin
  154.     name      := myName;
  155.     myColor   := color;
  156.     location  := ZeroPoint;
  157.     MyCtm.SetUnit;
  158. end; {baseObject.open}
  159.  
  160. (*******************************************************************************
  161. *                             BaseObject.CloseMe                               *
  162. *******************************************************************************)
  163. destructor BaseObject.CloseMe;
  164. begin
  165.     { I'm here so my children will Close-themselfs properly }
  166. end; {baseObject.closeMe}
  167.  
  168. (*******************************************************************************
  169. *                              BaseObject.move                                 *
  170. *******************************************************************************)
  171. procedure BaseObject.move(axis : axisType; by: real);
  172. begin
  173.        case axis of
  174.                x : begin
  175.                        myCtm.translateX(by);
  176.                        location.x :=location.x+by;
  177.                    end;
  178.                y : begin
  179.                        myCtm.translateY(by);
  180.                        location.y :=location.y+by;
  181.                    end;
  182.                z : begin
  183.                        myCtm.translateZ(by);
  184.                        location.z :=location.z+by;
  185.                    end;
  186.        end; {case}
  187.        scrPntUpdt := False;
  188. end; {BaseObject.move}
  189.  
  190. (*******************************************************************************
  191. *                            BaseObject.translate                              *
  192. *******************************************************************************)
  193. procedure BaseObject.translate(dx, dy, dz : integer);
  194. begin
  195.        myCtm.translate(dx,dy,dz);
  196.        location.x :=location.x+dx;
  197.        location.y :=location.y+dy;
  198.        location.z :=location.z+dz;
  199.        scrPntUpdt := False;
  200. end; {BaseObject.translate}
  201.  
  202. {use this routine when you know you need to translate more then one axis
  203.        before painting, you will use only one call, which will probably be
  204.        faster, and make your program easier to read, and maintain}
  205.  
  206. (*******************************************************************************
  207. *                              BaseObject.show                                 *
  208. *******************************************************************************)
  209. procedure BaseObject.show;
  210. var
  211.    myPen, oldPen : HPen;
  212. begin
  213.  {   setColor(myColor);    }
  214.     myPen := getStockObject(black_Pen);
  215.     oldPen := selectObject(dc, myPen);
  216.     paint(dc);
  217.     selectObject(dc, oldPen);
  218.     deleteObject(myPen);
  219. end; {baseObject.show}
  220.  
  221. (*******************************************************************************
  222. *                              BaseObject.hide                                 *
  223. *******************************************************************************)
  224. procedure BaseObject.hide;
  225. var
  226.    myPen, oldPen : HPen;
  227. begin
  228.     myPen := getStockObject(white_Pen);
  229.     oldPen := selectObject(dc, myPen);
  230.    { setColor(0);} {backGround}
  231.     paint(dc);      {at this color}
  232.     selectObject(dc, oldPen);
  233.     deleteObject(myPen);
  234. end; {baseObject.hide}
  235.  
  236. (*******************************************************************************
  237. *                              BaseObject.Paint                                *
  238. *******************************************************************************)
  239. procedure BaseObject.Paint;
  240. begin
  241.     if (not(scrPntUpdt)) then
  242.        updateScreenPoints;
  243.     { alas,  BaseObject cannot really paint becuase it does not have   }
  244.     { screen points (what a shame ...)                                 }
  245. end; {baseObject.paint}
  246.  
  247. (*******************************************************************************
  248. *                       BaseObject.UpdateScreenPoints                          *
  249. *******************************************************************************)
  250. procedure BaseObject.UpdateScreenPoints;
  251. begin
  252.     scrPntUpdt := True; { Have no screen points or any other points, so     }
  253.                         { points are already updated (I think)              }
  254. end; {updateScreenPoints}
  255.  
  256. (*******************************************************************************
  257. *                              BaseObject.scale                                *
  258. *******************************************************************************)
  259. procedure BaseObject.scale(axis : axisType; factor : real);
  260. begin
  261.        myCtm.translate(-location.x,-location.y,-location.z);
  262.        case axis of
  263.                x : myCtm.scaleX(factor);
  264.                y : myCtm.scaleY(factor);
  265.                z : myCtm.scaleZ(factor);
  266.        end; {scale}
  267.        myCtm.translate(location.x,location.y,location.z);
  268.        scrPntUpdt := False;
  269. end; {baseObject.scale}
  270.  
  271. (*******************************************************************************
  272. *                            BaseObject.allScale                               *
  273. *******************************************************************************)
  274. procedure BaseObject.allScale(sx,sy,sz : real);
  275. begin
  276.     myCtm.translate(-location.x, -location.y, -location.z);
  277.     myCtm.scale(sx,sy,sz);
  278.     myCtm.translate(location.x, location.y, location.z);
  279.     scrPntUpdt := False;
  280. end; {allScale}
  281. {call this routine to scale more then one axis at a time, with a single call}
  282.  
  283. (*******************************************************************************
  284. *                            BaseObject.goto3dPos                              *
  285. *******************************************************************************)
  286. procedure BaseObject.goto3dPos;
  287. begin
  288.        translate(round(x - location.x), round(y - location.y)
  289.                        , round(z - location.z));
  290. end; {baseObject.goto3dPos}
  291.  
  292. (*******************************************************************************
  293. *                           BaseObject.setToOrigin                             *
  294. *******************************************************************************)
  295. procedure BaseObject.setToOrigin;
  296. begin
  297.     goto3dPos(0, 0, 0);
  298.     myCtm.setUnit;
  299.     location := zeroPoint;
  300. end; {BaseObject.setToOrign}
  301.  
  302. (*******************************************************************************
  303. *                          BaseObject.CalcLocation                             *
  304. *******************************************************************************)
  305. procedure BaseObject.CalcLocation;
  306. begin
  307.     location := zeroPoint; { What else could it be when there are no points ?}
  308. end; {baseObject.calcLocation}
  309.  
  310. (*******************************************************************************
  311. *                         BaseObject.deleteTransform                           *
  312. *******************************************************************************)
  313. procedure BaseObject.deleteTransform;
  314. begin
  315.     myCtm.setUnit;
  316.     scrPntUpdt := false;
  317. end; {baseObject.deleteTransform}
  318.  
  319. (******************************************************************************
  320. *                              BaseObject.rotate                              *
  321. ******************************************************************************)
  322. procedure BaseObject.rotate;
  323. begin
  324.        myCtm.translate(-location.x,-location.y,-location.z);
  325.        case axis of
  326.                x :     myCtm.rotateX(deg);
  327.                y :     myCtm.rotateY(deg);
  328.                z :     myCtm.rotateZ(deg);
  329.        end; {case}
  330.        myCtm.translate(location.x,location.y,location.z);
  331.  
  332.        {rotation means : go to origin (translate -location),
  333.                          rotate       (rotate axis degrees),
  334.                          go to prev pos (translate location);
  335.        }
  336.  
  337.        scrPntUpdt := False;
  338. end; {BaseObject.rotate, see interface for comments}
  339.  
  340. (******************************************************************************
  341. *                               baseObject.load                               *
  342. ******************************************************************************)
  343. function baseObject.load;
  344. var
  345.     elementFile : f_real;
  346.     errC       : word;
  347. begin
  348.     {$i-} {supposed to be so, just making sure}
  349.     assign(elementFile,name);
  350.     reset(elementFile); {o.k. open it}
  351.     errC := ioResult;
  352.     load := errC;
  353.     if (errC = 0) then begin
  354.        readMe(elementFile);
  355.        errC := ioResult;
  356.        load := errC;
  357.        close(elementFile);
  358.        calcLocation;
  359.        scrPntUpdt := false;
  360.     end; {if}
  361. end; { baseObject.load}
  362.  
  363. (******************************************************************************
  364. *                               baseObject.save                               *
  365. ******************************************************************************)
  366. function baseObject.save;
  367. var
  368.     elementFile : f_real;
  369.     errC       : word;
  370. begin
  371.     {$i-} {supposed to be so, just making sure}
  372.     assign(elementFile,name);
  373.     rewrite(elementFile); {o.k. open it}
  374.     errC := ioResult;
  375.     save := errC;
  376.     if (errC = 0) then begin
  377.        writeMe(elementFile);
  378.        errC := ioResult; save := errC;
  379.        close(elementFile);
  380.     end; {if}
  381. end; {baseObject.save}
  382.  
  383. (******************************************************************************
  384. *                             baseObject.writeMe                              *
  385. ******************************************************************************)
  386. procedure baseObject.writeMe;
  387. begin
  388.    {override by descendents }
  389. end; {baseObject.writeMe}
  390.  
  391. (******************************************************************************
  392. *                              baseObject.readMe                              *
  393. ******************************************************************************)
  394. procedure baseObject.readMe;
  395. begin
  396.    {override by descendents }
  397. end; {baseObject.readMe}
  398.  
  399.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  400.     {                        Obj3d implementation                          }
  401.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  402.  
  403.  
  404. (*******************************************************************************
  405. *                                 Obj3d.open                                   *
  406. *******************************************************************************)
  407. constructor Obj3d.open;
  408. begin
  409.     BaseObject.Open(myName, color);
  410.     scrPntUpdt := False; {not calculated yet}
  411.     numOfLines := 0;
  412.     numOfPoints := 0;
  413.     myCtm.setUnit; {initialize to unit matrix}
  414.     reverseRot.setUnit;
  415.     unReverseRot.setUnit;
  416. end; {Obj3d.open}
  417.  
  418. (*******************************************************************************
  419. *                               Obj3d.CloseMe                                  *
  420. *******************************************************************************)
  421. destructor Obj3d.CloseMe;
  422. begin
  423. end;  {Obj3d.Close}
  424.  
  425.  
  426. (*******************************************************************************
  427. *                          Obj3d.updateScreenPoints                            *
  428. *******************************************************************************)
  429. procedure Obj3d.updateScreenPoints;
  430. var i : integer;
  431.     p : point3d;
  432. begin
  433.     for i := 1 to numOfPoints do begin
  434.        myCtm.transform(p, points[i]); {transform by ctm}
  435.        calcPoint(p, scrPoints[i]);
  436.     end; {for}
  437.     scrPntUpdt := True; {make sure for next time..}
  438.            {make all points ready}
  439. end; {obj3d.updateScreenPoints}
  440.  
  441. (*******************************************************************************
  442. *                                Obj3d.paint                                   *
  443. *******************************************************************************)
  444. procedure Obj3d.paint;
  445. {do the actual painting here}
  446. var
  447.     i : integer;
  448. begin
  449.     if ((numOfPoints = 0) or (numOfLines = 0)) then exit;
  450.     if (not(scrPntUpdt)) then
  451.        updateScreenPoints;
  452.     for i := 1 to numOfLines do begin
  453.        moveTo(dc, scrPoints[lines[i].fromP].sX, scrPoints[lines[i].fromP].sY);
  454.        lineTo(dc, scrPoints[lines[i].toP].sX, scrPoints[lines[i].toP].sY  );
  455.     end;
  456.     {it should be noted that calcPoint has to convert points to integers}
  457. end; {obj3d.paint}
  458.  
  459. (******************************************************************************
  460. *                                obj3d.readMe                                 *
  461. ******************************************************************************)
  462. procedure obj3d.readMe;
  463. var
  464.     tmp1,tmp2  : real;
  465.     i,j        : byte;
  466. begin
  467.        read(elementFile, tmp1);
  468.        numOfPoints := trunc(tmp1);
  469.        for j := 1 to numOfPoints do begin
  470.            read(elementFile, points[j].x);
  471.            read(elementFile, points[j].y);
  472.            read(elementFile, points[j].z);
  473.        end; {for}
  474.        read(elementFile, tmp1);
  475.        numOfLines := trunc(tmp1);
  476.        for j := 1 to numOfLines do begin
  477.            read(elementFile, tmp1, tmp2);
  478.            lines[j].fromP := trunc(tmp1);
  479.            lines[j].toP   := trunc(tmp2);
  480.        end; {for}
  481. end; {obj3d.readMe}
  482.  
  483. (******************************************************************************
  484. *                                obj3d.writeMe                                *
  485. ******************************************************************************)
  486. procedure obj3d.writeMe;
  487. var
  488.     tmp1,tmp2  : real;
  489.     i,j        : byte;
  490. begin
  491.        tmp1 := numOfPoints;
  492.        write(elementFile, tmp1);
  493.        for j := 1 to numOfPoints do begin
  494.            write(elementFile, points[j].x);
  495.            write(elementFile, points[j].y);
  496.            write(elementFile, points[j].z);
  497.        end; {for}
  498.        tmp1 := numOfLines;
  499.        write(elementFile, tmp1);
  500.        for j := 1 to numOfLines do begin
  501.            tmp1 := lines[j].fromP;
  502.            tmp2 := lines[j].toP;
  503.            write(elementFile, tmp1, tmp2);
  504.        end;
  505. end; {obj3d.writeMe}
  506.  
  507. (*******************************************************************************
  508. *                             obj3d.calcLocation                               *
  509. *******************************************************************************)
  510. procedure obj3d.calcLocation;
  511. var
  512.        ce : point3d;
  513.        p  : point3d;
  514.        i  : integer;
  515. begin
  516.        ce := zeroPoint; { (0, 0, 0) -> ce }
  517.        for i := 1 to numOfPoints do begin
  518.                myCtm.transform(p, points[i]);
  519.                ce.x := ce.x + p.x;
  520.                ce.y := ce.y + p.y;
  521.                ce.z := ce.z + p.z;
  522.        end; {for}
  523.        location.x := ce.x / numOfPoints;
  524.        location.y := ce.y / numOfPoints;
  525.        location.z := ce.z / numOfPoints;
  526. end; {obj3d.calcLocation}
  527.  
  528. (*******************************************************************************
  529. *                             Obj3d.setToOrigin                                *
  530. *******************************************************************************)
  531. procedure Obj3d.setToOrigin;
  532. var
  533.        i : integer;
  534.        p : point3d;
  535. begin
  536.     goto3dPos(0, 0, 0);
  537.     for i := 1 to numOfPoints do begin
  538.            myCtm.transform(p, points[i]);
  539.            points[i] := p;
  540.     end; {for}
  541.     scrPntUpdt := False; (** Instead of that THING above **)
  542.     myCtm.setUnit;
  543.     location := zeroPoint;
  544. end; {BaseObject.setToOrign}
  545.  
  546. (*******************************************************************************
  547. *                              ComplexObj.Open                                 *
  548. *******************************************************************************)
  549. constructor ComplexObj.Open;
  550. begin
  551.     BaseObject.Open(myName, color);
  552.     numOfChilds := 0;
  553. end; {complexObj.open}
  554.  
  555. (*******************************************************************************
  556. *                             ComplexObj.CloseMe                               *
  557. *******************************************************************************)
  558. destructor ComplexObj.CloseMe;
  559. var
  560.        i : integer;
  561.  
  562. begin
  563.        for i := 1 to numOfChilds do
  564.                dispose(childs[i],closeMe);
  565.        baseObject.closeMe;
  566. end; {complexObj.closeMe}
  567.  
  568. (*******************************************************************************
  569. *                          ComplexObj.addSubObject                             *
  570. *******************************************************************************)
  571. function ComplexObj.addSubObject;
  572. var
  573.     ret_code : word;
  574. begin
  575.        if (numOfChilds >= maxSubObjects) then begin
  576.                addSubObject := 255; {signal error}
  577.                exit;
  578.        end;
  579.        inc(numOfChilds);
  580.        childs[numOfChilds] := new(obj3dPtr, open(myName, zeroPoint, myColor));
  581.        ret_code := childs[numOfChilds]^.load;
  582.        if (ret_code = 0) then begin
  583.                with refPoint do
  584.                        childs[numOfChilds]^.translate(round(x),
  585.                                                round(y), round(z));
  586.                ctms[numOfChilds].copy(childs[numOfChilds]^.myCtm);
  587.        end; {if ret_c..}
  588.        addSubObject := ret_code;
  589. end; {complexObj.addSubObject}
  590.  
  591. (*******************************************************************************
  592. *                       complexObj.updateScreenPoints                          * 
  593. *******************************************************************************)
  594. procedure complexObj.updateScreenPoints;
  595. var
  596.     i : integer;
  597. begin
  598.     for i := 1 to numOfChilds do begin
  599.        childs[i]^.myCtm.multiply_2(ctms[i], myCtm);
  600.        childs[i]^.updateScreenPoints;
  601.     end;
  602.     scrPntUpdt := True;
  603. end; {complexObj.updateScreenPoints}
  604.  
  605. (*******************************************************************************
  606. *                           complexObj.getChildPtr                             *
  607. *******************************************************************************)
  608. function complexObj.getChildPtr;
  609. begin
  610.        getChildPtr := childs[index];
  611. end; {complexObj.getChildPtr}
  612.  
  613. (*******************************************************************************
  614. *                           ComplexObj.rotateChild                             *
  615. *******************************************************************************)
  616. procedure ComplexObj.rotateChild;
  617. begin
  618.     with childs[child]^ do begin
  619.        myCtm.copy(ctms[child]);
  620.        rotate(axis, deg);
  621.        ctms[Child].copy(MyCtm);
  622.        myCtm.Multiply(Self.myCtm);
  623.     end;
  624. end; {complexObj.rotateChild}
  625.  
  626. (*******************************************************************************
  627. *                           ComplexObj.scaleChild                              *
  628. *******************************************************************************)
  629. procedure ComplexObj.scaleChild;
  630. begin
  631.     with childs[child]^ do begin
  632.        myCtm.copy(ctms[child]);
  633.        scale(axis, factor);
  634.        ctms[Child].copy(MyCtm);
  635.        myCtm.Multiply(Self.myCtm);
  636.     end;
  637. end; {complexObj.scaleChild}
  638.  
  639. (*******************************************************************************
  640. *                            ComplexObj.moveChild                              *
  641. *******************************************************************************)
  642. procedure ComplexObj.moveChild;
  643. begin
  644.     with childs[child]^ do begin
  645.        myCtm.copy(ctms[child]);
  646.        move(axis, by);
  647.        ctms[Child].copy(MyCtm);
  648.        myCtm.Multiply(Self.myCtm);
  649.     end;
  650. end; {complexObj.moveChild}
  651.  
  652. (******************************************************************************
  653. *                              complexObj.paint                               *
  654. ******************************************************************************)
  655. procedure complexObj.paint;
  656. var
  657.        i : integer;
  658. begin
  659.     if (not(scrPntUpdt)) then
  660.        updateScreenPoints;
  661.     for i := 1 to numOfChilds do
  662.        childs[i]^.paint(dc);
  663. end; {complexObj.paint}
  664.  
  665. (******************************************************************************
  666. *                             complexObj.writeMe                              *
  667. ******************************************************************************)
  668. procedure complexObj.writeMe;
  669. var
  670.        i : integer;
  671.        r : real;
  672. begin
  673.        r := 0.0 + numOfChilds;
  674.        write(elementFile, r);
  675.        for i := 1 to numOfChilds do
  676.                childs[i]^.writeMe(elementFile); {let all the kids write themselvs}
  677. end; {complexObj.writeMe}
  678.  
  679. (******************************************************************************
  680. *                              complexObj.readMe                              *
  681. ******************************************************************************)
  682. procedure complexObj.readMe;
  683. var
  684.        i : integer;
  685.        r : real;
  686. begin
  687.        read(elementFile, r);
  688.        numOfChilds := round(r);
  689.        for i := 1 to numOfChilds do begin
  690.               childs[i] := new(Obj3dPtr, Open('Child', ZeroPoint, myColor));
  691.               childs[i]^.readMe(elementFile);
  692.               childs[i]^.calcLocation;
  693.               ctms[i].setUnit;
  694.        end; {for}
  695. end; {complexObj.readMe}
  696.  
  697. (******************************************************************************
  698. *                           complexObj.calcLocation                           *
  699. ******************************************************************************)
  700. procedure complexObj.calcLocation;
  701. var
  702.        i : integer;
  703. begin
  704.        location := zeroPoint;
  705.        for i := 1 to numOfChilds do
  706.                with childs[i]^ do begin
  707.                        calcLocation;
  708.                        self.location.x := location.x + self.location.x;
  709.                        self.location.y := location.y + self.location.y;
  710.                        self.location.z := location.z + self.location.z;
  711.                end; {with}
  712.        with location do begin
  713.                x := x / numOfChilds;
  714.                y := y / numOfChilds;
  715.                z := z / numOfChilds;
  716.        end; {with..}
  717. end; {complexObj.calclocation}
  718.  
  719. (******************************************************************************
  720. *                               complexObj.move                               *
  721. ******************************************************************************)
  722. procedure complexObj.move;
  723. var
  724.        i : integer;
  725. begin
  726. (*       for i := 1 to numOfChilds do
  727.                with childs[i]^ do
  728.                        case axis of
  729.                                x : location.x := location.x + by;
  730.                                y : location.y := location.y + by;
  731.                                z : location.z := location.z + by;
  732.                        end; {case}  *)
  733.        baseObject.move(axis, by);
  734. end; {complexObj.move}
  735.  
  736. (******************************************************************************
  737. *                              complexObj.rotate                              *
  738. ******************************************************************************)
  739. procedure complexObj.rotate;
  740. var
  741.        i : integer;
  742.        sint, cost : real;
  743. begin
  744. (*       cost := cos(deg / 180.0 * 3.1415926535897932385);
  745.        sint := sin(deg / 180.0 * 3.1415926535897932385);
  746.        for i := 1 to numOfChilds do
  747.                with childs[i]^ do
  748.                        case axis of
  749.                                x : begin
  750.                                        location.y := location.y * cost -
  751.                                                location.z * sint;
  752.                                        location.z := location.y * sint +
  753.                                                location.z * cost;
  754.                                end; {x}
  755.                                y : begin
  756.                                        location.x := location.x * cost +
  757.                                                location.z * sint;
  758.                                        location.z := location.z * cost -
  759.                                                location.x * sint;
  760.                                end; {y}
  761.                                z : begin
  762.                                        location.x := location.x * cost -
  763.                                                location.y * sint;
  764.                                        location.y := location.y * cost +
  765.                                                location.x * sint;
  766.                                end; {z}
  767.                        end; {case} *)
  768.        baseObject.rotate(axis, deg);
  769. end; {complexObj.rotate}
  770.  
  771. (******************************************************************************
  772. *                              complexObj.scale                               *
  773. ******************************************************************************)
  774. procedure complexObj.scale;
  775. var
  776.        i : integer;
  777. begin
  778. (*       for i := 1 to numOfChilds do
  779.                with childs[i]^ do
  780.                        case axis of
  781.                                x : location.x := location.x * factor;
  782.                                y : location.y := location.y * factor;
  783.                                z : location.z := location.z * factor;
  784.                        end; {case} *)
  785.        baseObject.scale(axis, factor);
  786. end; {complexObj.scale}
  787.  
  788. (******************************************************************************
  789. *                                    end.                                     *
  790. ******************************************************************************)
  791. end.
  792.